#ifndef _RUNTIME_H_JM_20110828_
#define _RUNTIME_H_JM_20110828_


#include "../boxes/BoxBaseTypes.h"
#include "BoxCreatorRegistrator.h"
#include "BoxModelCreator.h"

#include <sstream>

#include <bobox_runtime.hpp>

#include "../LogConf.h"

#ifdef BOBOX_VERSION_OLD
#include <bobox_request.hpp>
#endif
#ifdef BOBOX_VERSION_2_2
#include <bobox_object_factory.hpp>
#include <bobox_good_old_parser.hpp>
#include <bobox_boxes.hpp>
#endif
namespace jm4bbx {


class results : public bobox::results {
	virtual size_t get_tables_count() const { return 0; }
	virtual size_t get_rows_count(size_t table) const { return 0; }		
	virtual void get_rows(size_t table, size_t from, size_t count, 
		rows_type &rows) const { }
};

class request : public bobox::request {

public:
#ifdef BOBOX_VERSION_OLD
	request(bobox::request_id_type rqid, bobox::runtime *rt, 
		bobox::box_model *model) : bobox::request(rqid, rt, model) { }
#endif
#ifdef BOBOX_VERSION_2_2
	request(bobox::request_id_type rqid, bobox::runtime *rt, 
		bobox::box_model_ptr_type model)
		: bobox::request(rqid, rt, model, bobox::parameters_ptr_type()) { }
#endif

	virtual const bobox::results *get_results() const { return &results_; }
private:
	results results_;
};

#ifdef BOBOX_VERSION_OLD
	#define RUNTIME_PARENTS public bobox::runtime
#endif
#ifdef BOBOX_VERSION_2_2
	#define RUNTIME_PARENTS public bobox::runtime, public bobox::object_factory
#endif

////////////////////////////////////////////////////////////////////////////////
/// RUNTIME ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

class runtime :  RUNTIME_PARENTS {
		JM_USE_LOGGER(runtimeLogger)
private:
    
	virtual void destroy_impl() { }

#ifdef BOBOX_VERSION_OLD
    
	virtual void init_impl(const bofe::configuration &conf) { }

	virtual bobox::request* create_request_impl(const std::string &model, 
		bobox::request_id_type rqid) {
		
			bobox::model_box_model* m = new bobox::model_box_model(
				bobox::box_model_id_type(0), bobox::box_tid_type("model_box"), 
				model, this);

			return new request(rqid, this, m);
	}

	virtual bobox::box_model_ptr_type create_box_model_impl(
		bobox::box_model_id_type id, bobox::box_tid_type tid, 
		const plainParameters &params) {

			const std::string& rtid = tid;

			if (BoxCreatorRegistrator::getInstance()->isRegistered(rtid)) {
				BoxModelCreator* creator = 
					BoxCreatorRegistrator::getInstance()->getCreator(rtid);
				return creator->createBoxModel(BoxModelParamPack(id, tid, this, params));
			}
			assert("Neznamy typ boxu!" && false);
			return bobox::box_model_ptr_type();
	}

#endif
#ifdef BOBOX_VERSION_2_2
    virtual void init_impl() { }

	virtual bobox::request *create_request_impl(
		const bobox::box_model_ptr_type &model, bobox::request_id_type rqid, 
		const bobox::parameters_ptr_type &params) {		
			return new request(rqid, this, model);
	}

	virtual bobox::runtime *get_runtime() {
		return this; 
	}

	virtual bobox::box_model_ptr_type create_box_model_impl(
		const bobox::box_model_tid_type &tid, 
		const bobox::io_descriptors_type &input_descriptors, 
		const bobox::io_descriptors_type &output_descriptors, 
		const bobox::parameters_ptr_type &params) {
		
			const std::string& rtid = tid;
			if (BoxCreatorRegistrator::getInstance()->isRegistered(rtid)) {
				BoxModelCreator* creator = 
					BoxCreatorRegistrator::getInstance()->getCreator(rtid);
				
				bobox::box_model_parameters_pack boboxParamPack(this, 
					input_descriptors, output_descriptors);

				BoxModelParamPack pack(boboxParamPack, params);

				return creator->createBoxModel(pack);
			}
			LOG_E("Neznamy typ boxu: " << rtid);
			assert("Neznamy typ boxu!" && false);
			return bobox::box_model_ptr_type();
	}

#endif

#ifdef BOBOX_VERSION_OLD
#define CREATE_TYPE_DESCRIPTOR_PARAMETERS bobox::type_tid_type tid, const plainParameters &params
#endif
#ifdef BOBOX_VERSION_2_2
#define CREATE_TYPE_DESCRIPTOR_PARAMETERS const bobox::type_tid_type &tid, const bobox::parameters_ptr_type &params
#endif

	virtual bobox::type_descriptor_ptr_type create_type_descriptor_impl(
		CREATE_TYPE_DESCRIPTOR_PARAMETERS) {

			if (tid == bobox::type_tid_type("int"))
				return bobox::type_descriptor_ptr_type(
					new bobox::generic_type_descriptor<integerPolicyType>());
			if (tid == bobox::type_tid_type("string"))
				return bobox::type_descriptor_ptr_type(
					new bobox::generic_type_descriptor<stringPolicyType>());
			if (tid == bobox::type_tid_type("IntegerKeyRecord"))
				return bobox::type_descriptor_ptr_type(
					new bobox::generic_type_descriptor<IntegerKeyRecordPolicyType>());
			if (tid == bobox::type_tid_type("StringKeyRecord"))
				return bobox::type_descriptor_ptr_type(
					new bobox::generic_type_descriptor<StringKeyRecordPolicyType>());
			if (tid == bobox::type_tid_type("BinaryOperationResultIndex"))
				return bobox::type_descriptor_ptr_type(
				new bobox::generic_type_descriptor<BinaryOperationResultIndexPolicyType>());			
			assert(false);
			return bobox::type_descriptor_ptr_type();
	}

};

} // namespace jm4bbx

#endif
